package com.potenza.wxuser.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import java.lang.reflect.Method;

@Aspect
@Component
public class PerformanceAspect {

    /**
     * 切入点
     * 匹配包及其子包下的所有类的所有方法
     * Pointcut annotation
     */
    @Pointcut("@annotation(com.potenza.wxuser.annotation.Performance)")
    public void pointCut_perfAspect(){

    }


    /**
     * 后置异常通知
     * 定义一个名字，该名字用于匹配通知实现方法的一个参数名，
     * 当目标方法抛出异常返回后，将把目标方法抛出的异常传给通知方法；
     * throwing 只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知，否则不执行，
     */
    @Around("pointCut_perfAspect()")
    public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
        return pointCut_perfAspect(proceedingJoinPoint);
    }

    private Object pointCut_perfAspect(ProceedingJoinPoint proceedingJoinPoint) {
        MethodSignature signature = (MethodSignature) proceedingJoinPoint.getSignature();
        Method method = signature.getMethod();

        //请求的方法名
        String className = proceedingJoinPoint.getTarget().getClass().getName();
        String methodName = signature.getName();
        String name = className + "." + methodName;

        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        try {
            Object proceed = proceedingJoinPoint.proceed();//执行方法本身
            return proceed;
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }finally {

            stopWatch.stop();
            long totalTimeMillis = stopWatch.getTotalTimeMillis();
            System.out.println(name + " 执行（ms）" + totalTimeMillis);
        }
        return null;

    }





}
